package com.axzhengxin.platform.sync.impl;

import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.db.Db;
import cn.hutool.db.Entity;
import cn.hutool.db.ds.DSFactory;
import com.axzhengxin.platform.business.domain.BizFlowInfo;
import com.axzhengxin.platform.business.mapper.BizFlowInfoMapper;
import com.axzhengxin.platform.sync.ISyncDataService;
import com.ruoyi.common.utils.spring.SpringUtils;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.sql.DataSource;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * ApplyBizFlowInfoSyncServiceImpl
 * 造申请流程相关数据服务
 *
 * @author jiangnan
 * @date 2021/3/25
 */
@Slf4j
@Service
public class ApplyBizFlowInfoSyncServiceImpl implements ISyncDataService {

    private static final int ORDER = BizApplyInfoSyncServiceImpl.ORDER + 1;

    private static Map<Long, Long> deptAdminMapper;
    private Map<String, Function<Entity, BizFlowInfo>> mapFuncMapper = MapUtil
            .<String, Function<Entity, BizFlowInfo>>builder()
            .put("1", unallocatedBizFlowInfo())
            .put("2", processingBizFlowInfo())
            .put("4", acceptedBizFlowInfo())
            .put("6", rejectedBizFlowInfo())
            .build();

    @Autowired
    private BizFlowInfoMapper bizFlowInfoMapper;

    @Autowired
    private DataSource ecscDs;

    private static Function<Entity, BizFlowInfo> unallocatedBizFlowInfo() {
        return (entity -> {
            BizFlowInfo flow = basicMapperFunc().apply(entity);
            flow.setStatus(10);
            flow.setCreateBy(flow.getCurrentNodeUserId());
            return flow;
        });
    }

    private static Function<Entity, BizFlowInfo> processingBizFlowInfo() {
        return (entity -> {
            BizFlowInfo flow = basicMapperFunc().apply(entity);
            flow.setStatus(1010);
            flow.setCreateBy(flow.getCurrentNodeUserId());
            return flow;
        });
    }

    private static Function<Entity, BizFlowInfo> acceptedBizFlowInfo() {
        return (entity -> {
            BizFlowInfo flow = basicMapperFunc().apply(entity);
            flow.setStatus(2000);
            flow.setCreateBy(flow.getCurrentNodeUserId());
            return flow;
        });
    }

    private static Function<Entity, BizFlowInfo> rejectedBizFlowInfo() {
        return (entity -> {
            BizFlowInfo flow = basicMapperFunc().apply(entity);
            flow.setStatus(3000);
            flow.setCreateBy(flow.getCurrentNodeUserId());
            flow.setRejectReason(entity.getStr("REASON1"));
            return flow;
        });
    }

    private static Function<Entity, BizFlowInfo> basicMapperFunc() {
        return (entity -> {
            BizFlowInfo flow = new BizFlowInfo();
            flow.setBizId(entity.getStr("SERIALNO"));
            flow.setBizType("APPLY");
            flow.setCurrentNodeDeptId(entity.getStr("BRANCH"));
            flow.setCreateTime(entity.getDate("APPTIME"));
            if (StrUtil.isNotBlank(entity.getStr("GHJG"))) {
                flow.setCurrentNodeUserId(entity.getStr("GHJG"));
            } else {
                // 这里是找到对应机构管理员
                Long deptId = Long.parseLong(flow.getCurrentNodeDeptId());
                log.info("当前机构为:{}", deptId);
                if (deptAdminMapper.containsKey(deptId)) {
                    flow.setCurrentNodeUserId(String.valueOf(deptAdminMapper.get(deptId)));
                    log.info("当前机构或上级机构管理员为:{}", flow.getCurrentNodeUserId());
                } else {
                    log.info("当前机构或上级机构中没有管理员角色人员");
                }
            }
            return flow;
        });
    }

    @SneakyThrows
    @Override
    public void exec() {
        String profile = SpringUtils.getActiveProfile();
        preExec();
        Db.use(DSFactory.get(profile))
                // 读取所有待分配、已处理、已拒绝的申请
                .find(Entity.create("syd_apply_info").set("flag", new String[]{"1", "2", "4", "6"}))
                .stream()
                // 不处理任何没有机构管辖的业务
                .filter(entity -> StrUtil.isNotBlank(entity.getStr("BRANCH")))
                // 不处理没有同步到biz_apply_info的业务
                .filter(entity -> {
                    String reqId = entity.getStr("TRANSSERIALNO");
                    try {
                        Number count = Db.use(ecscDs).queryNumber("select count(1) from biz_apply_info where req_id = ?", reqId);
                        return count.intValue() > 0;
                    } catch (Exception ex) {
                        log.error("读取已同步的申请信息失败", ex);
                        return false;
                    }
                })
                // 按状态分组
                .collect(Collectors.groupingBy(entity -> entity.getStr("FLAG")))
                .entrySet()
                .stream()
                // 使用对应状态的转换器进行处理
                .flatMap(entry -> entry.getValue()
                        .stream()
                        .map(e -> mapFuncMapper.get(entry.getKey()).apply(e)))
                // 写入数据库
                .forEach(bizFlowInfoMapper::insertBizFlowInfo);
    }

    @SneakyThrows
    private void preExec() {
        deptAdminMapper = loadDeptAdminMapper();
    }

    @Override
    public int getOrder() {
        return ORDER;
    }

}
